home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / text / hyper / ADtoHT2_1.lha / Source.lha / Includes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-23  |  21.6 KB  |  819 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. /************************************************************************/
  6.  
  7. #include "main.h"
  8. #include "File.h"
  9. #include "ProcessDir.h"
  10. #include "Includes.h"
  11. #include "Autodocs.h"
  12. #include "FormatNode.h"
  13. #include "AdditionalDocs.h"
  14.  
  15. /************************************************************************/
  16.  
  17. struct AVLTree IncludeFileTree = {NULL, nodecasecmp};
  18. struct AVLTree StructureTree = {NULL, nodecmp};
  19. struct AVLTree UnionTree = {NULL, nodecmp};
  20. struct AVLTree TypedefTree = {NULL, nodecmp};
  21. struct AVLTree DefinesTree = {NULL, nodecmp};
  22.  
  23. /************************************************************************/
  24. /*                                                                      */
  25. /* Create a new IncludeItemNodeNode                                     */
  26. /*                                                                      */
  27. /************************************************************************/
  28.  
  29. static struct IncludeItemNodeNode *
  30. CreateIncludeItem (char *Name,
  31.            struct AVLTree *Tree,
  32.            struct IncludeFileNode *IncludeFileNode,
  33.            ULONG Line)
  34.  
  35. {
  36.   struct IncludeItemNode *IncludeItemNode;
  37.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  38.   struct IncludeItemNodeNode **Current;
  39.  
  40.   if (!(IncludeItemNode = (struct IncludeItemNode *) SearchNode (Tree, Name)))
  41.     {
  42.       IncludeItemNode = (struct IncludeItemNode *) CreateNode (Name, sizeof (*IncludeItemNode));
  43.       IncludeItemNode->Entries = NULL;
  44.       IncludeItemNode->Function = FALSE;
  45.       AVL_InsertNode (Tree, &IncludeItemNode->AnyNode.AVLNode);
  46.     }
  47.   IncludeItemNodeNode = xmalloc (sizeof (*IncludeItemNodeNode));
  48.   IncludeItemNodeNode->IncludeFileNode = IncludeFileNode;
  49.   IncludeItemNodeNode->IncludeItemNode = IncludeItemNode;
  50.   IncludeItemNodeNode->Line = Line;
  51.  
  52.   Current = &(IncludeItemNode->Entries);
  53.   while (*Current)
  54.     {
  55.       int Result;
  56.  
  57.       Result = strcasecmp ((*Current)->IncludeFileNode->AnyNode.Name,
  58.             IncludeItemNodeNode->IncludeFileNode->AnyNode.Name);
  59.       if (Result > 0)
  60.     {
  61.       break;
  62.     }
  63.       if (Result == 0)
  64.     {
  65.       if ((*Current)->Line > IncludeItemNodeNode->Line)
  66.         {
  67.           break;
  68.         }
  69.     }
  70.       Current = &((*Current)->Next);
  71.     }
  72.   IncludeItemNodeNode->Next = *Current;
  73.   *Current = IncludeItemNodeNode;
  74.  
  75.   return IncludeItemNodeNode;
  76. }
  77.  
  78. /************************************************************************/
  79. /*                                                                      */
  80. /* Write a word, creating links to #defines and typedefs                */
  81. /*                                                                      */
  82. /************************************************************************/
  83.  
  84. void
  85. WriteIdentifier (struct Word *Word, struct IncludeFileNode *CurrentIncludeFile)
  86.  
  87. {
  88.   if (Pass2)
  89.     {
  90.       if (Word->Length > 1)
  91.     {
  92.       struct IncludeItemNode *IncludeItemNode;
  93.  
  94.       WriteWhitespace (Word);
  95.  
  96.       if ((IncludeItemNode = (struct IncludeItemNode *) SearchNode (&DefinesTree, Word->Word)) ||
  97.           (IncludeItemNode = (struct IncludeItemNode *) SearchNode (&TypedefTree, Word->Word)))
  98.         {
  99.           struct IncludeItemNodeNode *IncludeItemNodeNode;
  100.  
  101.           IncludeItemNodeNode = IncludeItemNode->Entries;
  102.           while (IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile)
  103.         {
  104.           IncludeItemNodeNode=IncludeItemNodeNode->Next;
  105.         }
  106.           if (IncludeItemNodeNode)
  107.         {
  108.           WPrintf ("@{\x22%s\x22 LINK File %lu}",
  109.                Word->Word, IncludeItemNodeNode->Line);
  110.         }
  111.           else
  112.         {
  113.           IncludeItemNodeNode=IncludeItemNode->Entries;
  114.           WPrintf ("@{\x22%s\x22 LINK \x22%s/File\x22 %lu}",
  115.                Word->Word,
  116.                IncludeItemNodeNode->IncludeFileNode->LinkName,
  117.                IncludeItemNodeNode->Line);
  118.         }
  119.           return;
  120.         }
  121.     }
  122.       WriteWord (Word);
  123.     }
  124. }
  125.  
  126. /************************************************************************/
  127. /*                                                                      */
  128. /* Read a C token, handling comments                                    */
  129. /*                                                                      */
  130. /************************************************************************/
  131.  
  132. static struct Word *ReadToken (int AllowEOF, struct IncludeFileNode *CurrentIncludeFile)
  133.  
  134. {
  135.   struct Word *Word;
  136.  
  137.   do
  138.     {
  139.       Word = ReadWord (AllowEOF);
  140.       if (Word->Word[0] == '/')
  141.     {
  142.       struct Word *NextWord;
  143.  
  144.       NextWord = ReadWord (FALSE);
  145.       if (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '*')
  146.         {
  147.           /* found a comment */
  148.           WriteWord (Word);
  149.           FreeWord (Word);
  150.           WriteWord (NextWord);
  151.           FreeWord (NextWord);
  152.           ConvertNodeText (TRUE, CurrentIncludeFile);
  153.           Word = NULL;
  154.         }
  155.       else
  156.         {
  157.           UnreadWord (NextWord);
  158.         }
  159.     }
  160.     }
  161.   while (!Word);
  162.   return Word;
  163. }
  164.  
  165. /************************************************************************/
  166. /*                                                                      */
  167. /* Look for the "current" node in a tree.                */
  168. /* If that node is found, write it (creating a link if necessary).    */
  169. /* If that node is not found, return NULL and don't write anything.    */
  170. /*                                                                      */
  171. /************************************************************************/
  172.  
  173. static struct IncludeItemNodeNode *DoCurrentItem(struct IncludeFileNode *CurrentIncludeFile,
  174.                          ULONG CurrentLine,
  175.                          struct Word *Word,
  176.                          struct AVLTree *Tree,
  177.                          int CheckAutodocs)
  178.  
  179. {
  180.   struct IncludeItemNode *IncludeItemNode;
  181.  
  182.   if ((IncludeItemNode=(struct IncludeItemNode *)SearchNode(Tree,Word->Word)))
  183.     {
  184.       struct IncludeItemNodeNode *IncludeItemNodeNode;
  185.  
  186.       for (IncludeItemNodeNode=IncludeItemNode->Entries;
  187.        (IncludeItemNodeNode &&
  188.         (IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile || IncludeItemNodeNode->Line!=CurrentLine));
  189.        IncludeItemNodeNode=IncludeItemNodeNode->Next)
  190.     ;
  191.       if (IncludeItemNodeNode)
  192.     {
  193.       struct IncludeItemNodeNode *LinkDestNode;
  194.  
  195.       if ((LinkDestNode=IncludeItemNodeNode->Next))
  196.         {
  197.         DoIncludeLink:
  198.           WriteWhitespace(Word);
  199.           WPrintf ("@{\x22");
  200.           WriteWord (Word);
  201.           WPrintf ("\x22 LINK \x22");
  202.           if (LinkDestNode->IncludeFileNode != CurrentIncludeFile)
  203.         {
  204.           WPrintf ("%s/", LinkDestNode->IncludeFileNode->LinkName);
  205.         }
  206.           WPrintf ("File\x22 %lu}", LinkDestNode->Line);
  207.         }
  208.       else
  209.         {
  210.           if (!CheckAutodocs || !DoAutodoc (Word, NULL))
  211.         {
  212.           LinkDestNode=IncludeItemNode->Entries;
  213.           if (LinkDestNode->Next)
  214.             {
  215.               goto DoIncludeLink;
  216.             }
  217.           WriteWord (Word);
  218.         }
  219.         }
  220.     }
  221.       return IncludeItemNodeNode;
  222.     }
  223.   return NULL;
  224. }
  225.  
  226. /************************************************************************/
  227. /*                                                                      */
  228. /* Handle struct/union stuff                                            */
  229. /* This function is expected to read the struct/union as first word     */
  230. /* Returns the name of the variable (i.e. the last name before the ';'  */
  231. /*                                                                      */
  232. /************************************************************************/
  233.  
  234. static struct Word *
  235. StructUnion (struct IncludeFileNode *CurrentIncludeFile)
  236.  
  237. {
  238.   static unsigned int BlockDepth;
  239.   static struct IncludeItemNodeNode *CurrentStructure;
  240.  
  241.   struct Word *StartWord;
  242.   struct Word *IdentifierWord;
  243.   struct Word *Word;
  244.   struct Word *VariableWord;
  245.  
  246.   if (!BlockDepth)
  247.     {
  248.       CurrentStructure = NULL;
  249.     }
  250.   BlockDepth++;
  251.  
  252.   VariableWord = NULL;
  253.   StartWord = ReadWord (FALSE);
  254.   WriteWhitespace (StartWord);
  255.  
  256.   IdentifierWord = ReadToken (FALSE, CurrentIncludeFile);
  257.   if (IdentifierWord->Word[0] != '{')
  258.     {
  259.       /* named struct/union */
  260.       /* struct Identifier ... */
  261.  
  262.       Word = ReadToken (FALSE, CurrentIncludeFile);
  263.       if (Word->Word[0] != '{')
  264.     {
  265.       /* struct/union usage */
  266.       /* struct Identifier Object */
  267.  
  268.       if (Pass2)
  269.         {
  270.           struct IncludeItemNode *IncludeItemNode;
  271.  
  272.           if ((IncludeItemNode = (struct IncludeItemNode *)
  273.            SearchNode (StartWord->Word[0] == 'u' ?
  274.                    &UnionTree : &StructureTree,
  275.                    IdentifierWord->Word)))
  276.         {
  277.           struct IncludeItemNodeNode *IncludeItemNodeNode;
  278.  
  279.           for (IncludeItemNodeNode = IncludeItemNode->Entries;
  280.                IncludeItemNodeNode && IncludeItemNodeNode!=CurrentStructure;
  281.                IncludeItemNodeNode=IncludeItemNodeNode->Next)
  282.             ;
  283.           if (!IncludeItemNodeNode)
  284.             {
  285.               for (IncludeItemNodeNode=IncludeItemNode->Entries;
  286.                IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile;
  287.                IncludeItemNodeNode=IncludeItemNodeNode->Next)
  288.             ;
  289.               if (!IncludeItemNodeNode)
  290.             {
  291.               IncludeItemNodeNode=IncludeItemNode->Entries;
  292.             }
  293.               if (!IdentifierWord->Newline)
  294.             {
  295.               WPrintf ("@{\x22");
  296.               WriteWord (StartWord);
  297.             }
  298.               else
  299.             {
  300.               WriteWord (StartWord);
  301.               WPrintf ("@{\x22");
  302.             }
  303.               WriteWord (IdentifierWord);
  304.               if (CurrentIncludeFile == IncludeItemNodeNode->IncludeFileNode)
  305.             {
  306.               WPrintf ("\x22 LINK File %lu}", IncludeItemNodeNode->Line);
  307.             }
  308.               else
  309.             {
  310.               WPrintf ("\x22 LINK \x22%s/File\x22 %lu}",
  311.                    IncludeItemNodeNode->IncludeFileNode->LinkName,
  312.                    IncludeItemNodeNode->Line);
  313.             }
  314.             }
  315.           else
  316.             {
  317.               WriteWord (StartWord);
  318.               WriteWord (IdentifierWord);
  319.             }
  320.         }
  321.           else
  322.         {
  323.           WriteWord (StartWord);
  324.           WriteWord (IdentifierWord);
  325.         }
  326.         }
  327.       do
  328.         {
  329.           WriteWord (Word);
  330.           if (Word->Length > 1 || !Word->Special)
  331.         {
  332.           FreeWord (VariableWord);
  333.           VariableWord = Word;
  334.         }
  335.           else
  336.         {
  337.           FreeWord (Word);
  338.         }
  339.           Word = ReadToken (FALSE, CurrentIncludeFile);
  340.         }
  341.       while (Word->Word[0] != ';' && Word->Word[0] != ')');
  342.       UnreadWord (Word);
  343.       FreeWord (IdentifierWord);
  344.       FreeWord (StartWord);
  345.       BlockDepth--;
  346.       return VariableWord;
  347.     }
  348.       else
  349.     {
  350.       /* struct/union definition */
  351.       /* struct Identifier {...} */
  352.  
  353.       WriteWord (StartWord);
  354.       if (!Pass2)
  355.         {
  356.           if (BlockDepth == 1)
  357.         {
  358.           CurrentStructure=CreateIncludeItem (IdentifierWord->Word,
  359.                               StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
  360.                               CurrentIncludeFile,
  361.                               StartWord->Line);
  362.         }
  363.         }
  364.       else
  365.         {
  366.           if (BlockDepth==1)
  367.         {
  368.           CurrentStructure=DoCurrentItem(CurrentIncludeFile,
  369.                          StartWord->Line,
  370.                          IdentifierWord, 
  371.                          StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
  372.                          FALSE);
  373.         }
  374.           else
  375.         {
  376.           WriteWord (IdentifierWord);
  377.         }
  378.         }
  379.     }
  380.       WriteWord (Word);
  381.       FreeWord (Word);
  382.     }
  383.   else
  384.     {
  385.       WriteWord (StartWord);
  386.     }
  387.   FreeWord (StartWord);
  388.   FreeWord (IdentifierWord);
  389.  
  390.   /* Take care of the structure body */
  391.   /* {...}; */
  392.  
  393.   Word = ReadToken (FALSE, CurrentIncludeFile);
  394.   while (Word)
  395.     {
  396.       if (Word->Word[0] == '}')
  397.     {
  398.       WriteWord (Word);
  399.       FreeWord (Word);
  400.       Word = NULL;
  401.     }
  402.       else if (!strcmp (Word->Word, "struct") ||
  403.            !strcmp (Word->Word, "union"))
  404.     {
  405.       UnreadWord (Word);
  406.       FreeWord (StructUnion (CurrentIncludeFile));
  407.       Word = ReadToken (FALSE, CurrentIncludeFile);
  408.     }
  409.       else
  410.     {
  411.       WriteIdentifier (Word, CurrentIncludeFile);
  412.       if (Word->Length > 1 || !Word->Special)
  413.         {
  414.           FreeWord (VariableWord);
  415.           VariableWord = Word;
  416.         }
  417.       else
  418.         {
  419.           FreeWord (Word);
  420.         }
  421.       Word = ReadToken (FALSE, CurrentIncludeFile);
  422.     }
  423.     }
  424.   Word = ReadToken (FALSE, CurrentIncludeFile);
  425.   while (Word->Word[0] != ';')
  426.     {
  427.       WriteWord (Word);
  428.       if (Word->Length > 1 || !Word->Special)
  429.     {
  430.       FreeWord (VariableWord);
  431.       VariableWord = Word;
  432.     }
  433.       else
  434.     {
  435.       FreeWord (Word);
  436.     }
  437.       Word = ReadToken (FALSE, CurrentIncludeFile);
  438.     }
  439.   UnreadWord (Word);
  440.   BlockDepth--;
  441.   return VariableWord;
  442. }
  443.  
  444. /************************************************************************/
  445. /*                                                                      */
  446. /* Functions to be called from FormatNode()/PrintLink()            */
  447. /*                                                                      */
  448. /************************************************************************/
  449.  
  450. struct FormatParameters
  451. {
  452.   struct IncludeFileNode *IncludeFileNode;
  453.   struct AVLTree *Tree;
  454.  
  455.   struct AVLStateInfo StateInfo;
  456.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  457. };
  458.  
  459. /************************************************************************/
  460.  
  461. static char *
  462. NextLabel (char *PrevLabel, void *Parameters)
  463.  
  464. {
  465.   struct FormatParameters *Params;
  466.   struct IncludeItemNode *IncludeItemNode;
  467.  
  468.   Params = Parameters;
  469.  
  470.   if (!PrevLabel)
  471.     {
  472.       AVL_InitTraversal (Params->Tree, &Params->StateInfo);
  473.     }
  474.   else
  475.     {
  476.       free (PrevLabel);
  477.     }
  478.  
  479.   while ((IncludeItemNode=(struct IncludeItemNode *)AVL_InOrder(&Params->StateInfo)))
  480.     {
  481.       for (Params->IncludeItemNodeNode=IncludeItemNode->Entries;
  482.        Params->IncludeItemNodeNode && Params->IncludeItemNodeNode->IncludeFileNode!=Params->IncludeFileNode;
  483.        Params->IncludeItemNodeNode=Params->IncludeItemNodeNode->Next)
  484.     ;
  485.       if (Params->IncludeItemNodeNode)
  486.     {
  487.       char *Label, *t;
  488.  
  489.       Label=xmalloc(strlen(IncludeItemNode->AnyNode.Name)+3);
  490.       t=stpcpy(Label,IncludeItemNode->AnyNode.Name);
  491.       if (IncludeItemNode->Function)
  492.         {
  493.           stpcpy(t,"()");
  494.         }
  495.       return Label;
  496.     }
  497.     }
  498.   return NULL;
  499. }
  500.  
  501. /************************************************************************/
  502. /*                                                                      */
  503. /* Print the link information                                           */
  504. /*                                                                      */
  505. /************************************************************************/
  506.  
  507. static void 
  508. PrintLink (void *Parameters)
  509.  
  510. {
  511.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  512.  
  513.   IncludeItemNodeNode = ((struct FormatParameters *) Parameters)->IncludeItemNodeNode;
  514.   WPrintf ("\x22%s/File\x22 %lu",
  515.        IncludeItemNodeNode->IncludeFileNode->LinkName,
  516.        IncludeItemNodeNode->Line);
  517. }
  518.  
  519. /************************************************************************/
  520. /*                                                                      */
  521. /* Output the table of contents                                         */
  522. /*                                                                      */
  523. /************************************************************************/
  524.  
  525. static void 
  526. WriteTOC (struct IncludeFileNode *IncludeFileNode)
  527.  
  528. {
  529.   int i;
  530.  
  531.   WPrintf ("\n@NODE MAIN \x22%s\x22\n", IncludeFileNode->AnyNode.Name);
  532.   if (GlobalTOCFilename)
  533.     {
  534.       WPrintf("@TOC \x22%s/MAIN\x22\n",GlobalTOCFilename);
  535.     }
  536.   WPrintf ("\n@{\x22%s\x22 LINK File}\n", IncludeFileNode->AnyNode.Name);
  537.  
  538.   for (i=0; i<4; i++)
  539.     {
  540.       static struct
  541.     {
  542.       char *Header;
  543.       struct AVLTree *Tree;
  544.     } TOCParagraph[4]=
  545.       {
  546.         {"Structures",&StructureTree},
  547.         {"Unions",&UnionTree},
  548.         {"Typedefs",&TypedefTree},
  549.         {"#defines",&DefinesTree}
  550.       };
  551.  
  552.       struct FormatParameters FormatParameters;
  553.       char *Label;
  554.  
  555.       FormatParameters.IncludeFileNode = IncludeFileNode;
  556.       FormatParameters.Tree=TOCParagraph[i].Tree;
  557.       if ((Label=NextLabel(NULL,&FormatParameters)))
  558.     {
  559.       int *ColWidth;
  560.  
  561.       free (Label);
  562.       ColWidth = FormatNode (NextLabel, &FormatParameters);
  563.       WPrintf (*Arguments.Version >= 39 ? "\n\n@{b}%s@{ub}\n\n" : "\n\n%s\n\n", TOCParagraph[i].Header);
  564.       PrintNode (NextLabel, PrintLink, &FormatParameters, ColWidth);
  565.       free (ColWidth);
  566.     }
  567.     }
  568.   WPrintf ("\n@ENDNODE\n");
  569. }
  570.  
  571. /************************************************************************/
  572. /*                                                                      */
  573. /* Process a single include file.                                       */
  574. /*                                                                      */
  575. /************************************************************************/
  576.  
  577. static void
  578. ProcessIncludeFile (struct IncludeFileNode *CurrentIncludeFile)
  579.  
  580. {
  581.   struct Word *Word;
  582.   struct Word *TypedefWord, *TypedefName;
  583.   ULONG DefineCount;
  584.  
  585.   DefineCount = 0;
  586.  
  587.   ROpen (INCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
  588.   WOpen (HYPERINCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
  589.  
  590.   if (!Pass2)
  591.     {
  592.       CurrentIncludeFile->LinkName =
  593.     Arguments.FullPath ? xstrdup (WriteFilename) : CurrentIncludeFile->AnyNode.Name;
  594.     }
  595.  
  596.   WriteHeader (CurrentIncludeFile->LinkName, ReadFilename);
  597.  
  598.   if (Pass2)
  599.     {
  600.       WriteTOC (CurrentIncludeFile);
  601.     }
  602.  
  603.   TypedefWord = TypedefName = NULL;
  604.  
  605.   WPrintf ("@NODE File \x22%s\x22\n", CurrentIncludeFile->AnyNode.Name);
  606.   Word = ReadToken (FALSE, CurrentIncludeFile);
  607.   while (Word->Length)
  608.     {
  609.       if (Word->Length == 1 && Word->Special)
  610.     {
  611.       /* one character special "words" */
  612.       if (Word->Word[0] == '#')
  613.         {
  614.           /* Found a preprocessor command */
  615.  
  616.           WriteWord (Word);
  617.           FreeWord (Word);
  618.           Word = ReadWord (FALSE);
  619.           WriteWord (Word);
  620.           if (!strcmp (Word->Word, "include"))
  621.         {
  622.           /* #include */
  623.           FreeWord (Word);
  624.           Word = ReadWord (FALSE);
  625.           if (Pass2)
  626.             {
  627.               if (Word->Word[0] == '"' || Word->Word[0] == '<')
  628.             {
  629.               char *Filename;
  630.               struct IncludeFileNode *IncludeFileNode;
  631.  
  632.               WriteWord (Word);
  633.               Filename = ReadUntil (Word->Word[0] == '"' ? "\x22" : ">");
  634.               FreeWord (Word);
  635.               Word = ReadWord (FALSE);
  636.               if ((IncludeFileNode = (struct IncludeFileNode *) SearchNode (&IncludeFileTree, Filename)))
  637.                 {
  638.                   WPrintf ("@{\x22%s", Filename);
  639.                   WriteWhitespace (Word);
  640.                   WPrintf ("\x22 LINK \x22%s/File\x22}", IncludeFileNode->LinkName);
  641.                 }
  642.               else
  643.                 {
  644.                   WPrintf ("%s", Filename);
  645.                 }
  646.               WriteWord (Word);
  647.               FreeWord (Word);
  648.               Word = ReadWord (TRUE);
  649.               free (Filename);
  650.             }
  651.               else
  652.             {
  653.               fprintf (stderr, "%s, line %lu;\nError: Illegal #include syntax\n",
  654.                    ReadFilename, Word->Line);
  655.  
  656.               SetRC (RETURN_ERROR);
  657.             }
  658.             }
  659.           while (!Word->Newline)
  660.             {
  661.               WriteWord (Word);
  662.               FreeWord (Word);
  663.               Word = ReadWord (FALSE);
  664.             }
  665.         }
  666.           else if (!strcmp (Word->Word, "define") && DefineCount++)
  667.         {
  668.           /* #define */
  669.           FreeWord (Word);
  670.           Word = ReadWord (FALSE);
  671.           if (!Pass2)
  672.             {
  673.               struct IncludeItemNodeNode *IncludeItemNodeNode;
  674.               struct Word *NextWord;
  675.  
  676.               IncludeItemNodeNode = CreateIncludeItem (Word->Word,
  677.                                    &DefinesTree,
  678.                                    CurrentIncludeFile,
  679.                                    Word->Line);
  680.               NextWord = ReadWord (FALSE);
  681.               IncludeItemNodeNode->IncludeItemNode->Function =
  682.             (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '(');
  683.               UnreadWord (NextWord);
  684.             }
  685.           else
  686.             {
  687.               DoCurrentItem(CurrentIncludeFile, Word->Line, Word, &DefinesTree, TRUE);
  688.             }
  689.           FreeWord (Word);
  690.           Word = ReadWord (TRUE);
  691.         }
  692.           else
  693.         {
  694.           /* Unknown preprocessor command */
  695.           FreeWord (Word);
  696.           Word = ReadWord (TRUE);
  697.           while (Word->Length && !Word->Newline)
  698.             {
  699.               WriteWord (Word);
  700.               FreeWord (Word);
  701.               Word = ReadWord (TRUE);
  702.             }
  703.         }
  704.         }
  705.       else if (Word->Word[0] == ';')
  706.         {
  707.           if (TypedefWord)
  708.         {
  709.           if (TypedefName)
  710.             {
  711.               if (!Pass2)
  712.             {
  713.               CreateIncludeItem(TypedefName->Word,&TypedefTree,CurrentIncludeFile,TypedefWord->Line);
  714.             }
  715.               FreeWord (TypedefName);
  716.               TypedefName=NULL;
  717.             }
  718.           FreeWord (TypedefWord);
  719.           TypedefWord=NULL;
  720.         }
  721.           WriteWord (Word);
  722.           FreeWord (Word);
  723.           Word = ReadWord (TRUE);
  724.         }
  725.       else
  726.         {
  727.           WriteWord (Word);
  728.           FreeWord (Word);
  729.           Word = ReadWord (TRUE);
  730.         }
  731.     }
  732.       else if (!strcmp (Word->Word, "struct") ||
  733.            !strcmp (Word->Word, "union"))
  734.     {
  735.       UnreadWord (Word);
  736.       TypedefName = StructUnion (CurrentIncludeFile);
  737.       if (!TypedefWord)
  738.         {
  739.           FreeWord (TypedefName);
  740.           TypedefName=NULL;
  741.         }
  742.       Word = ReadWord (TRUE);
  743.     }
  744.       else if (!strcmp (Word->Word, "typedef"))
  745.     {
  746.       WriteWord (Word);
  747.       TypedefWord = Word;
  748.       TypedefName = NULL;
  749.       Word = ReadWord (FALSE);
  750.     }
  751.       else
  752.     {
  753.       if (TypedefWord)
  754.         {
  755.           struct Word *NextWord;
  756.  
  757.           NextWord = ReadToken (FALSE, CurrentIncludeFile);
  758.           if (NextWord->Word[0] == ')' || NextWord->Word[0]==';')
  759.         {
  760.           TypedefName = Word;
  761.           if (!DoCurrentItem(CurrentIncludeFile, TypedefWord->Line, Word, &TypedefTree, FALSE))
  762.             {
  763.               WriteWord (Word);
  764.             }
  765.         }
  766.           else
  767.         {
  768.           WriteIdentifier (Word, CurrentIncludeFile);
  769.           FreeWord (Word);
  770.         }
  771.           UnreadWord (NextWord);
  772.         }
  773.       else
  774.         {
  775.           WriteIdentifier (Word, CurrentIncludeFile);
  776.           FreeWord (Word);
  777.         }
  778.       Word = ReadWord (TRUE);
  779.     }
  780.       UnreadWord (Word);
  781.       Word = ReadToken (TRUE, CurrentIncludeFile);
  782.     }
  783.   FreeWord (Word);
  784.   WPrintf ("\n@ENDNODE\n");
  785.   WClose ();
  786.   RClose ();
  787. }
  788.  
  789. /************************************************************************/
  790. /*                                                                      */
  791. /* Process a single include file, first pass.                           */
  792. /*                                                                      */
  793. /************************************************************************/
  794.  
  795. void
  796. ProcessIncludeFile1 (char *Filename)
  797.  
  798. {
  799.   struct IncludeFileNode *IncludeFileNode;
  800.  
  801.   IncludeFileNode = (struct IncludeFileNode *) CreateNode (Filename, sizeof (struct IncludeFileNode));
  802.   AVL_InsertNode (&IncludeFileTree, (struct AVLNode *) IncludeFileNode);
  803.   ProcessIncludeFile (IncludeFileNode);
  804. }
  805.  
  806. /************************************************************************/
  807. /*                                                                      */
  808. /* Process a single include file, second pass.                          */
  809. /*                                                                      */
  810. /************************************************************************/
  811.  
  812. void
  813. ProcessIncludeFile2 (struct IncludeFileNode *IncludeFileNode)
  814.  
  815. {
  816.   printf ("Converting %s\n", IncludeFileNode->AnyNode.Name);
  817.   ProcessIncludeFile (IncludeFileNode);
  818. }
  819.